home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / measure.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  229 lines

  1. /*
  2.  * $Id: measure.c,v 0.91 1994/02/20 00:53:26 zhao Pre-Release $
  3.  *
  4.  *. This file is part of BIT shareware package. After the two weeks of
  5.  *  free evaluation period, you are encouraged (required) to register
  6.  *  your copy for a small registration fee, which is $35 for personal use
  7.  *  and $50 for commercial, government and institutional use.
  8.  *
  9.  *  Copyright(c) 1993, 1994 by T.C. Zhao.
  10.  *  All rights reserved.
  11.  *
  12.  *  Permission to use, copy, and distribute this software in its entirety
  13.  *  for non-commercial purposes is hereby granted, provided that the
  14.  *  above shareware and copyright notices and this permission notice
  15.  *  appear in all copies and their documentation.
  16.  *
  17.  *  This software may be modified for your own use, but modified versions
  18.  *  may not be distributed without prior consent of the author.
  19.  *
  20.  *  This software is provided "as is" without expressed or implied
  21.  *  warranty of any kind.
  22.  *
  23.  *.
  24.  *
  25.  * Measure intensities along a line. Assuming square pixels, and distances
  26.  * are in terms of pixel-pixel distance.
  27.  */
  28.  
  29. #include "bit.h"
  30. #include "dmalloc.h"
  31. #include "extern.h"
  32.  
  33. /* get the RGB intensity and Grayscale or colorindex */
  34. #include <math.h>
  35. #include "lookup.h"
  36. #define PI  3.1415926
  37.  
  38. /* given a line, get theta between -180 and 180 */
  39. void
  40. get_theta(int w, int h, float *theta)
  41. {
  42.  
  43.     if ((Abs(w) + Abs(h)) < 5)
  44.     return;
  45.     if (w == 0)
  46.       {
  47.       *theta = (h > 0) ? 90.0 : -90.0;
  48.       }
  49.     else if (h == 0)
  50.       {
  51.       *theta = (w > 0) ? 0.0 : 180.0;
  52.       }
  53.     else
  54.       {
  55.       *theta = atan2(h, w) * 180.0 / PI;
  56.       }
  57. }
  58. static float *yy[4], *xx;
  59. static float ymin[] =
  60. {
  61.     0, 0, 0, 0
  62. };
  63. static float ymax[] =
  64. {
  65.     PCMAX - 1, PCMAX - 1, PCMAX - 1, PCMAX - 1
  66. };
  67.  
  68. static void
  69. get_lmem(int n)
  70. {
  71.     yy[0] = malloc(sizeof(float) * n);
  72.     yy[1] = malloc(sizeof(float) * n);
  73.     yy[2] = malloc(sizeof(float) * n);
  74.     yy[3] = malloc(sizeof(float) * n);
  75.     xx = malloc(sizeof(float) * n);
  76. }
  77.  
  78. static void
  79. free_lmem(void)
  80. {
  81.     free(yy[0]);
  82.     free(yy[1]);
  83.     free(yy[2]);
  84.     free(yy[3]);
  85.     free(xx);
  86. }
  87.  
  88. /*
  89.  * Get intensity along theta and show it. X-axis will be the distance (in
  90.  * pixels) along theta. No interpolation is done
  91.  */
  92. static void
  93. scan_int(IPTR im, float theta, int x, int y, int w, int h)
  94. {
  95.     double dx, dy;
  96.     double st = sin(theta * PI / 180.0), tt = tan(theta * PI / 180.0);
  97.     int aw, ah;
  98.     int ix, iy, ii, iimax;
  99.     rgba_t pix;
  100.     ci_t ci;
  101.     int r, g, b;
  102.     char title[40];
  103.  
  104.     aw = Abs(w);
  105.     ah = Abs(h);
  106.     tt = Abs(tt);
  107.     iimax = Max(aw, ah);
  108.     get_lmem(iimax + 1);
  109.  
  110.     /* always try to get maximum no. */
  111.     for (ii = 0; ii < iimax; ii++)
  112.       {
  113.       if (aw > ah)
  114.         {            /* move horizontally */
  115.         dx = (w > 0) ? ii : -ii;
  116.         dy = tt * ii;
  117.         dy = (h > 0) ? dy : -dy;
  118.         }
  119.       else
  120.         {            /* move vertically */
  121.         dy = (h > 0) ? ii : -ii;
  122.         dx = (w == 0) ? 0 : (ii / tt);
  123.         dx = (w > 0) ? dx : -dx;
  124.         if (w > 0)
  125.             dx = Abs(dx);
  126.         }
  127.       xx[ii] = (h == 0) ? dx : (dy / st);
  128.  
  129.       ix = (x - im->xi + dx);
  130.       iy = (y - im->yi + dy);
  131.  
  132.       if (IS_CPACK(im))
  133.         {
  134.         pix = ((rgba_t **) im->mraster)[iy][ix];
  135.         Unpack(pix, r, g, b);
  136.         yy[0][ii] = r;
  137.         yy[1][ii] = g;
  138.         yy[2][ii] = b;
  139.         yy[3][ii] = RGB2GRAY(r, g, b);
  140.         }
  141.       else
  142.         {            /* ci_t */
  143.         ci = ((ci_t **) im->mraster)[iy][ix];
  144.         ci &= (PCMAX - 1);
  145.         yy[0][ii] = im->cmap->ct[0][ci];
  146.         yy[1][ii] = im->cmap->ct[1][ci];
  147.         yy[2][ii] = im->cmap->ct[2][ci];
  148.         yy[3][ii] = ci;
  149.         }
  150.       }
  151.  
  152.     /* show whatever we've got */
  153.     set_chart4_style(FL_LINE_XYPLOT);
  154.     set_chart4_text("Red", "Green", "Blue", IS_CI(im) ? "Colorindex" : "Gray");
  155.     sprintf(title, "t=%.1f", theta);
  156.     for (ix = 0; ix < 4; ix++)
  157.     ymax[ix] = IS_CI(im) ? (im->cmap->colors - 1) : (PCMAX - 1);
  158.     set_chart4_ybounds(ymin, ymax);
  159.     show_chart4(title, xx, yy, ii);
  160.     free_lmem();
  161. }
  162. static int bdcolor = 1;
  163. static int
  164. handle_pup(void)
  165. {
  166.     static long phandle = -1;
  167.     int ret = 0;
  168.  
  169.     if (phandle < 0)
  170.     phandle = defpup("LinearScan%t|Help|LColor|Return");
  171.     switch (dopup(phandle))
  172.       {
  173.       case 1:
  174.       help_cb(0, HELP_LSCAN);
  175.       break;
  176.       case 2:
  177.       rubber_hide();
  178.       ++bdcolor;
  179.       bdcolor %= over_pup_colors;
  180.       rubber_show(bdcolor);
  181.       break;
  182.       case 3:
  183.       ret = 1;
  184.       break;
  185.       }
  186.     return ret;
  187. }
  188.  
  189. int
  190. img_measure(IPTR im)
  191. {
  192.     long dev;
  193.     short val;
  194.     int x, y, w, h, done = 0;
  195.     float t;
  196.  
  197.     set_rubber_bounds(1, im->xi, im->yi, im->w, im->h);
  198.     set_rubber_obj(RB_LINE);
  199.     x = (im->xi + im->xf) / 2;
  200.     y = (im->yi + im->yf) / 2;
  201.     w = h = Min(im->w, im->h) / 2;
  202.     while (!done)
  203.       {
  204.       dev = rubber_info(win_id, &val, &x, &y, &w, &h, bdcolor, 15);
  205.       /* note: rubber_info returns the no. of pixels, not distance. */
  206.       get_theta((w - 1), (h - 1), &t);
  207.       switch (dev)
  208.         {
  209.         case REDRAW:
  210.         if (val == win_id)
  211.             repaint(im, val);
  212.         break;
  213.         case ESCKEY:
  214.         done = val;
  215.         break;
  216.         case MENUBUTTON:
  217.         done = (val && handle_pup());
  218.         break;
  219.         default:
  220.         done = (dev == KEYBD && val == 27);
  221.         if (!done && (dev == LEFTMOUSE || dev == MIDDLEMOUSE) && val)
  222.             scan_int(im, t, x, y, (w - 1), (h - 1));
  223.         break;
  224.         }
  225.       }
  226.     rubber_finish();
  227.     return 0;
  228. }
  229.